package com.ehotting.eaf.security.aspect;

import com.ehotting.eaf.core.exception.BlackIpException;
import com.ehotting.eaf.core.utils.ip.IpUtils;
import com.ehotting.eaf.security.utils.BlackIpUtils;
import com.ehotting.eaf.core.domain.system.api.SysIp;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.util.List;

/**
 * 黑名单IP拦截
 */
@Aspect
@Component
@Slf4j
public class BlackIpAspect {

    @Pointcut("within(@org.springframework.web.bind.annotation.RestController *)")
    public void pointcut() {

    }

    @Around("pointcut()")
    public Object around(ProceedingJoinPoint point) throws Throwable {

        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
        String requestURI = request.getRequestURI();

        //判断是否为黑名单用户
        String ip = IpUtils.getIpAddr(request);
//        log.info("ip is :{}, requestURI is {}", ip, requestURI);

        if (checkIpBlack(ip)) {
            //ip在黑名单中返回true
            throw new BlackIpException("该ip被禁止访问");
        }

        return point.proceed();
    }

    //对比当前请求IP是否在黑名单中，注意（对比黑名单ip存放在redis中）
    public boolean checkIpBlack(String ip) throws Exception {
        List<SysIp> ipCache = BlackIpUtils.getIpCache();
        if (CollectionUtils.isEmpty(ipCache)) {
            return false;
        }
        return ipCache.stream().anyMatch(item -> item.getIp().equals(ip));
    }
}